home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Mania 6
/
MacMania 6.toast
/
/
Multimedia & Desktop
/
VideoToolbox
/
VideoToolboxSources
/
MoveMouse.c
< prev
next >
Wrap
Text File
|
1996-03-04
|
16KB
|
482 lines
/*
* MoveMouse.c
*
* Based on code from Jon Wtte, Denis Pelli, Apple, and a timely suggestion
* from Bo Lindbergh. This code checks to see if the Cursor Device Manager (CDM)
* is present. If it is, it uses the CDM calls; otherwise, it directly jabs low memory,
* in the traditional manner.
*
* Also included is glue for all of the CDM routines. On the PowerPC, the CDM glue is
* currently (11/95) missing from InterfaceLib. Since InterfaceLib is a shared library, you can't
* assume the glue will be present on a target machine. So this code includes
* its own glue, the construction of which is thanks to a helpful suggestion from Bo Lindbergh.
*
* For documentation of the CDM, see Apple Tech Note "HW 01 - ADB (The Untold Story: Space Aliens
* ate my mouse)".
*
* - Dan Sears (sears@netcom.com)
* From Apple Developer Services:
*
* In the past, moving the cursor programatically on the Macintosh has
* entailed the manipulation of low memory globals. This has worked for
* all macs for quite some time. But with the advent of the power book
* series and many 3rd party track balls, it has become apparent that the
* low memory globals no longer contained adequate information for the
* system to truly support all types of positioning devices. So, with the
* new Centris CPU's, and CPU's from all lines after we are implementing a
* new tool set that provides a much more comprehensive set of utilities
* for dealing with the cursor location and mouse button state. We call
* this new manager the Cursor Device Manager, and DTS will be documenting
* it in a future tech not, but since many machines are now shipping that
* do not use the traditional low memory globals to get the mouse location
* and position the mouse, it is important to "leak" a little of the tech
* note information early.
*
* First, the CDM (Cursor device manager) has its own trap ($AADB) and you
* can determine if a machine supports the CDM by using the standard TrapAvailable
* routine. (See inside mac for the source code to Trap
* Available). Once you have determined that the CDM exists, you should
* try not to use the low memory globals RawMouse and MTemp to get the
* current cursor location, or set a new cursor location. Instead the CDM
* provides 3 calls which you can use to get this info, the first is
* CrsrDevNextDevice which will give you the next cursor device record in
* the CDM list, if you pass it a NULL, it will give you the head of the
* list. Once you have the first cursor device you can use it to get the
* Cursor data record which contains the current cursor location in its
* where field. You can set the current location with either the
* CrsrDevMove (which moves relative to the current location) or the
* CrsrDevMoveTo (which moves to an absolute location) routines.
*
* The following is some sample code which implement some generic routines
* that work on all macintoshes. These routines are written not for speed
* but for clarity, so if you are writing a device driver or time critical
* code there are some things that you can do to speed up these routines,
* like predetermine at the outset if the CDM exists, this way you
* wouldn't have to check every time you want to use it, and getting the
* cursor device only once and keeping the pointer to it around between
* calls.
*
* HISTORY:
* 8/94 dgp Downloaded from ftp://nada.kth.se/pub/hacks/mac-faq/MoveMouse.c
* 10/94 dgp made minimal changes so that it would compile in CodeWarrior C. Untested.
* 12/94 dgp updated for compatibility with Universal Header "CursorDevices.h". Untested.
* 1/5/95 dgp updated for compatiblity with Universal Headers 2, in which
* CursorDevices.h was extensively changed. Untested.
* 6/26/95 dgp cosmetic changes. Still untested.
* 11/10/95 cbs Added missing InterfaceLib glue
11/13/95 dgp renamed glue routines from "glueCallCursorDevice..." to "CallCursorDevice..."
11/13/95 dgp renamed glue routines from "glueCallCursorDevice..." to "CallCursorDevice..."
*/
#if UNIVERSAL_HEADERS<2
#error "Compiling this file requires a reasonably recent (1995 or later) copy of CursorDevices.h"
#endif
#ifndef __CURSORDEVICES__
#include <CursorDevices.h>
#endif
#ifndef __TRAPS__
// this is much quicker than looking for and reading the Traps.h header file.
#define _CursorDeviceDispatch 0xAADB
#define _Unimplemented 0xA89F
// #include <Traps.h>
#endif
/*
* Glue routines for the Cursor Device Manager
*/
OSErr CallCursorDeviceMove(CursorDevicePtr ourDevice, long deltaX, long deltaY);
OSErr CallCursorDeviceMoveTo(CursorDevicePtr ourDevice, long absX, long absY);
OSErr CallCursorDeviceFlush(CursorDevicePtr ourDevice);
OSErr CallCursorDeviceButtons(CursorDevicePtr ourDevice, short buttons);
OSErr CallCursorDeviceButtonDown(CursorDevicePtr ourDevice);
OSErr CallCursorDeviceButtonUp(CursorDevicePtr ourDevice);
OSErr CallCursorDeviceButtonOp(CursorDevicePtr ourDevice, short buttonNumber, ButtonOpcode opcode, long data);
OSErr CallCursorDeviceSetButtons(CursorDevicePtr ourDevice, short numberOfButtons);
OSErr CallCursorDeviceSetAcceleration(CursorDevicePtr ourDevice, Fixed acceleration);
OSErr CallCursorDeviceDoubleTime(CursorDevicePtr ourDevice, long durationTicks);
OSErr CallCursorDeviceUnitsPerInch(CursorDevicePtr ourDevice, Fixed resolution);
OSErr CallCursorDeviceNextDevice(CursorDevicePtr *ourDevice);
OSErr CallCursorDeviceNewDevice(CursorDevicePtr *ourDevice);
OSErr CallCursorDeviceDisposeDevice(CursorDevicePtr ourDevice);
/*
* Low memory globals for the mouse
*/
#define xRawMouse 0x082C // low memory global that has current mouse loc
#define xMTemp 0x0828 // low memory global that has current mouse loc
#define xCrsrNew 0x08CE // set after you change mtemp and rawmouse
#define xCrsrCouple 0x08CF // true if the cursor is tied to the mouse
void GetMouseDevicePosition(Point *currentPoint);
void SetMouseDevicePosition(Point newPoint);
void SetMouseDevicePositionRel(Point newPoint);
Boolean IsCDMAvailable(void);
#if GENERATINGPOWERPC
enum {
glueUppCursorDeviceMoveProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (long))),
glueUppCursorDeviceMoveToProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (long))),
glueUppCursorDeviceFlushProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))),
glueUppCursorDeviceButtonsProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (short))),
glueUppCursorDeviceButtonDownProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))),
glueUppCursorDeviceButtonUpProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))),
glueUppCursorDeviceButtonOpProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (short))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (ButtonOpcode))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(4,SIZE_CODE(sizeof (long))),
glueUppCursorDeviceSetButtonsProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (short))),
glueUppCursorDeviceSetAccelerationProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (Fixed))),
glueUppCursorDeviceDoubleTimeProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))),
glueUppCursorDeviceUnitsPerInchProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (Fixed))),
glueUppCursorDeviceNextDeviceProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr *))),
glueUppCursorDeviceNewDeviceProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr *))),
glueUppCursorDeviceDisposeDeviceProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr)))
};
#endif
#if !GENERATINGPOWERPC
pascal void CallCursorTask(void)
= {
0x2078,0x08EE, // MOVE.L jCrsrTask,A0
0x4E90 // JSR (A0)
};
#endif
void
GetMouseDevicePosition(
Point *currentPoint)
{
CursorDevice *firstMouse;
long delay;
if (IsCDMAvailable()) {
firstMouse = NULL; // start at head of cursor dev list
CallCursorDeviceNextDevice(&firstMouse); // get the next cursor device
Delay(1, &delay); // why is this necessary?! cbs
*currentPoint = firstMouse->whichCursor->where;
} else
*currentPoint = *(Point *) xRawMouse; // use the low memory global
}
void
SetMouseDevicePosition(
Point newPoint)
{
CursorDevice *firstMouse;
if (IsCDMAvailable()) {
firstMouse = NULL;
CallCursorDeviceNextDevice(&firstMouse);
CallCursorDeviceMoveTo(firstMouse, (long) newPoint.h, (long) newPoint.v);
} else {
*(Point *) xRawMouse = newPoint;
*(Point *) xMTemp = newPoint;
*(Ptr) xCrsrNew = *(Ptr) xCrsrCouple; // Set CrsrNew if coupled
#if !GENERATINGPOWERPC
CallCursorTask(); // must call jCrsrTask to update system
#endif
}
}
void
SetMouseDevicePositionRel(
Point newPoint)
{
CursorDevice *firstMouse;
Point tempPt;
if (IsCDMAvailable()) {
firstMouse = NULL;
CallCursorDeviceNextDevice(&firstMouse);
CallCursorDeviceMove(firstMouse, (long) newPoint.h, (long) newPoint.v);
} else {
tempPt = *(Point *) xRawMouse;
tempPt.h += newPoint.h;
tempPt.v += newPoint.v;
*(Point *) xRawMouse = tempPt;
*(Point *) xMTemp = tempPt;
*(Ptr) xCrsrNew = *(Ptr) xCrsrCouple;
#if !GENERATINGPOWERPC
CallCursorTask();
#endif
}
}
Boolean IsCDMAvailable(void)
{
return NGetTrapAddress(_CursorDeviceDispatch, ToolTrap)
!= NGetTrapAddress(_Unimplemented, ToolTrap);
}
OSErr CallCursorDeviceMove(
CursorDevicePtr ourDevice,
long deltaX,
long deltaY)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceMoveToProcInfo,
0, ourDevice, deltaX, deltaY);
#else
return CursorDeviceMove(ourDevice, deltaX, deltaY);
#endif
}
OSErr
CallCursorDeviceMoveTo(
CursorDevicePtr ourDevice,
long absX,
long absY)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceMoveToProcInfo,
1, ourDevice, absX, absY);
#else
return CursorDeviceMoveTo(ourDevice, absX, absY);
#endif
}
OSErr
CallCursorDeviceFlush(
CursorDevicePtr ourDevice)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceFlushProcInfo,
0x2, ourDevice);
#else
return CursorDeviceFlush(ourDevice);
#endif
}
OSErr
CallCursorDeviceButtons(
CursorDevicePtr ourDevice,
short buttons)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceButtonsProcInfo,
0x3, ourDevice, buttons);
#else
return CursorDeviceButtons(ourDevice, buttons);
#endif
}
OSErr
CallCursorDeviceButtonDown(
CursorDevicePtr ourDevice)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceButtonDownProcInfo,
0x4, ourDevice);
#else
return CursorDeviceButtonDown(ourDevice);
#endif
}
OSErr
CallCursorDeviceButtonUp(
CursorDevicePtr ourDevice)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceButtonUpProcInfo,
0x5, ourDevice);
#else
return CursorDeviceButtonUp(ourDevice);
#endif
}
OSErr
CallCursorDeviceButtonOp(
CursorDevicePtr ourDevice,
short buttonNumber,
ButtonOpcode opcode,
long data)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceButtonOpProcInfo,
0x6, ourDevice, buttonNumber, opcode, data);
#else
return CursorDeviceButtonOp(ourDevice, buttonNumber, opcode, data);
#endif
}
OSErr
CallCursorDeviceSetButtons(
CursorDevicePtr ourDevice,
short numberOfButtons)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceSetButtonsProcInfo,
0x7, ourDevice, numberOfButtons);
#else
return CursorDeviceSetButtons(ourDevice, numberOfButtons);
#endif
}
OSErr
CallCursorDeviceSetAcceleration(
CursorDevicePtr ourDevice,
Fixed acceleration)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceSetAccelerationProcInfo,
0x8, ourDevice, acceleration);
#else
return CursorDeviceSetAcceleration(ourDevice, acceleration);
#endif
}
OSErr
CallCursorDeviceDoubleTime(
CursorDevicePtr ourDevice,
long durationTicks)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceDoubleTimeProcInfo,
0x9, ourDevice, durationTicks);
#else
return CursorDeviceDoubleTime(ourDevice, durationTicks);
#endif
}
OSErr
CallCursorDeviceUnitsPerInch(
CursorDevicePtr ourDevice,
Fixed resolution)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceUnitsPerInchProcInfo,
0xA, ourDevice, resolution);
#else
return CursorDeviceUnitsPerInch(ourDevice, resolution);
#endif
}
OSErr
CallCursorDeviceNextDevice(
CursorDevicePtr *ourDevice)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceNextDeviceProcInfo,
0xB, ourDevice);
#else
return CursorDeviceNextDevice(ourDevice);
#endif
}
OSErr
CallCursorDeviceNewDevice(
CursorDevicePtr *ourDevice)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceNewDeviceProcInfo,
0xC, ourDevice);
#else
return CursorDeviceNewDevice(ourDevice);
#endif
}
OSErr
CallCursorDeviceDisposeDevice(
CursorDevicePtr ourDevice)
{
#if GENERATINGPOWERPC
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
glueUppCursorDeviceDisposeDeviceProcInfo,
0xD, ourDevice);
#else
return CursorDeviceDisposeDevice(ourDevice);
#endif
}